From 80e9aa067860c7240dce2a0095340907b26d3e63 Mon Sep 17 00:00:00 2001 From: oliskoli Date: Fri, 18 Apr 2008 22:00:46 +0000 Subject: [PATCH] msroute: Try to detect records instead of calculating various (unknown) header lengths. --- gpsbabel/msroute.c | 73 ++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/gpsbabel/msroute.c b/gpsbabel/msroute.c index 754172b50..c3fb767c4 100644 --- a/gpsbabel/msroute.c +++ b/gpsbabel/msroute.c @@ -2,7 +2,7 @@ Support for Microsoft AutoRoute 2002 ".axe" files, - Copyright (C) 2005,2007 Olaf Klein, o.b.klein@gpsbabel.org + Copyright (C) 2005,2007,2008 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -566,17 +566,15 @@ ole_deinit(void) static void msroute_read_journey(void) { - int len; + int bufsz; char *buff; - buff = ole_read_property_stream(MSROUTE_OBJ_NAME, &len); + buff = ole_read_property_stream(MSROUTE_OBJ_NAME, &bufsz); - if ((buff != NULL) && (len > 0)) + if ((buff != NULL) && (bufsz > 0)) { msroute_head_t *head = (msroute_head_t *)buff; - char *cin; - int len; - char text[256]; + unsigned char *cin, *cend; int count = 0; route_head *route; waypoint *wpt; @@ -587,7 +585,8 @@ msroute_read_journey(void) version = buff[0x14]; is_fatal((version < 1) || (version > 7), MYNAME ": Unsupported version %d!", version); - cin = buff + 71; // sizeof(msroute_head_t); + cin = (unsigned char *)buff + 71; // (at least?) sizeof(msroute_head_t); + cend = (unsigned char *)buff + bufsz; route = route_head_alloc(); route_add_head(route); @@ -596,47 +595,51 @@ msroute_read_journey(void) while (count < head->waypts) { - double lat, lon; - short test; + int len; - cin++; - if (version == 7) cin+=8; + /* after version 6 we've seen data with different header length */ + /* now we try to find the next pair of names in buff */ + + while (1) { + len = *cin; + if ((cin + 120) > cend) { + cin = NULL; + break; + } + if ((cin + len < cend) && /* within buff ? */ + (cin[len + 3] == 0xff) && /* 0xff before next length byte ? */ + (cin[len + 4] == len) && /* wide string of same length ? */ + (le_read16(cin + len + 1) == 0xfeff)) { + break; + } + cin++; + } + if (cin == NULL) break; - len = *cin++; - strncpy(text, cin, len); - text[len] = '\0'; + wpt = waypt_new(); - cin += len + 1; - test = le_read16(cin); - is_fatal((test != -2), MYNAME ": Unsupported byte order within data (%d).", test); - - cin += 2; + len = *cin++; /* length of shortname */ + cin += len; + cin += 3; /* 0xfffeff */ - len = *cin; /* skip wide-string 'name' */ - cin += (len * 2) + 1; - + len = *cin++; + wpt->shortname = cet_str_uni_to_utf8((const short *)cin, len); + cin += (len * 2); /* seek over wide string */ cin += (5 * sizeof(gbint32)); /* five unknown DWORDs */ /* offs 12 !!!! Latitude int32 LE */ /* offs 16 !!!! Longitude int32 LE */ - - lat = GPS_Math_Semi_To_Deg(le_read32(cin+12)); - lon = GPS_Math_Semi_To_Deg(le_read32(cin+16)); + wpt->latitude = GPS_Math_Semi_To_Deg(le_read32(cin+12)); + wpt->longitude = GPS_Math_Semi_To_Deg(le_read32(cin+16)); cin += (23 * sizeof(gbint32)); cin += 3; - - count++; - - wpt = waypt_new(); - - wpt->latitude = lat; - wpt->longitude = lon; - wpt->shortname = xstrdup(text); + #ifdef OLE_DEBUG waypt_add(waypt_dupe(wpt)); /* put to wpt-list to see results if no output is specified */ #endif route_add_wpt(route, wpt); + count++; } } @@ -676,5 +679,5 @@ ff_vecs_t msroute_vecs = { NULL, NULL, msroute_args, - CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ + CET_CHARSET_UTF8, 1 /* CET-REVIEW */ }; -- 2.30.2